<template>
    <view class="tui-datetime-picker">
        <view
            class="tui-mask"
            :class="{ 'tui-mask-show': isShow }"
            @touchmove.stop.prevent="stop"
            catchtouchmove="stop"
            @tap="hide"
        ></view>
        <view class="tui-header" :class="{ 'tui-show': isShow }">
            <view
                class="tui-picker-header"
                :class="{ 'tui-date-radius': radius }"
                :style="{ backgroundColor: headerBackground }"
                @touchmove.stop.prevent="stop"
                catchtouchmove="stop"
            >
                <view
                    class="tui-btn-picker"
                    :style="{ color: cancelColor }"
                    hover-class="tui-opacity"
                    :hover-stay-time="150"
                    @tap="hide"
                    >取消</view
                >
                <view
                    class="tui-btn-picker"
                    :style="{ color: color }"
                    hover-class="tui-opacity"
                    :hover-stay-time="150"
                    @tap="btnFix"
                    >确定</view
                >
            </view>
            <view
                class="tui-date-header"
                :style="{ backgroundColor: unitBackground }"
                v-if="unitTop"
            >
                <view class="tui-date-unit" v-if="type < 4 || type == 7"
                    >年</view
                >
                <view class="tui-date-unit" v-if="type < 4 || type == 7"
                    >月</view
                >
                <view
                    class="tui-date-unit"
                    v-if="type == 1 || type == 2 || type == 7"
                    >日</view
                >
                <view
                    class="tui-date-unit"
                    v-if="type == 1 || type == 4 || type == 5 || type == 7"
                    >时</view
                >
                <view class="tui-date-unit" v-if="type == 1 || type > 3"
                    >分</view
                >
                <view class="tui-date-unit" v-if="type > 4">秒</view>
            </view>
            <view
                class="tui-picker-body"
                :style="{ backgroundColor: bodyBackground }"
            >
                <picker-view
                    :value="value"
                    @change="change"
                    class="tui-picker-view"
                >
                    <picker-view-column
                        v-if="!reset && (type < 4 || type == 7)"
                    >
                        <view
                            class="tui-column-item"
                            :class="{
                                'tui-font-size_32': !unitTop && type == 7
                            }"
                            v-for="(item, index) in years"
                            :key="index"
                        >
                            {{ item }}
                            <text class="tui-unit-text" v-if="!unitTop"
                                >年</text
                            >
                        </view>
                    </picker-view-column>
                    <picker-view-column
                        v-if="!reset && (type < 4 || type == 7)"
                    >
                        <view
                            class="tui-column-item"
                            :class="{
                                'tui-font-size_32': !unitTop && type == 7
                            }"
                            v-for="(item, index) in months"
                            :key="index"
                        >
                            {{ formatNum(item) }}
                            <text class="tui-unit-text" v-if="!unitTop"
                                >月</text
                            >
                        </view>
                    </picker-view-column>
                    <picker-view-column
                        v-if="!reset && (type == 1 || type == 2 || type == 7)"
                    >
                        <view
                            class="tui-column-item"
                            :class="{
                                'tui-font-size_32': !unitTop && type == 7
                            }"
                            v-for="(item, index) in days"
                            :key="index"
                        >
                            {{ formatNum(item) }}
                            <text class="tui-unit-text" v-if="!unitTop"
                                >日</text
                            >
                        </view>
                    </picker-view-column>
                    <picker-view-column
                        v-if="
                            !reset &&
                                (type == 1 ||
                                    type == 4 ||
                                    type == 5 ||
                                    type == 7)
                        "
                    >
                        <view
                            class="tui-column-item"
                            :class="{
                                'tui-font-size_32': !unitTop && type == 7
                            }"
                            v-for="(item, index) in hours"
                            :key="index"
                        >
                            {{ formatNum(item) }}
                            <text class="tui-unit-text" v-if="!unitTop"
                                >时</text
                            >
                        </view>
                    </picker-view-column>
                    <picker-view-column
                        v-if="!reset && (type == 1 || type > 3)"
                    >
                        <view
                            class="tui-column-item"
                            :class="{
                                'tui-font-size_32': !unitTop && type == 7
                            }"
                            v-for="(item, index) in minutes"
                            :key="index"
                        >
                            {{ formatNum(item) }}
                            <text class="tui-unit-text" v-if="!unitTop"
                                >分</text
                            >
                        </view>
                    </picker-view-column>
                    <picker-view-column v-if="!reset && type > 4">
                        <view
                            class="tui-column-item"
                            :class="{
                                'tui-font-size_32': !unitTop && type == 7
                            }"
                            v-for="(item, index) in seconds"
                            :key="index"
                        >
                            {{ formatNum(item) }}
                            <text class="tui-unit-text" v-if="!unitTop"
                                >秒</text
                            >
                        </view>
                    </picker-view-column>
                </picker-view>
            </view>
        </view>
    </view>
</template>

<script>
export default {
    name: 'tuiDatetime',
    props: {
        //1-日期+时间（年月日+时分） 2-日期(年月日) 3-日期(年月) 4-时间（时分） 5-时分秒 6-分秒 7-年月日 时分秒
        type: {
            type: Number,
            default: 1
        },
        //年份区间
        startYear: {
            type: Number,
            default: 1980
        },
        //年份区间
        endYear: {
            type: Number,
            default: 2050
        },
        //"取消"字体颜色
        cancelColor: {
            type: String,
            default: '#888'
        },
        //"确定"字体颜色
        color: {
            type: String,
            default: '#5677fc'
        },
          //设置默认显示日期 2019-08-01 || 2019-08-01 17:01 || 2019/08/01
        setDateTime: {
            type: String,
            default: ''
        },
        //单位置顶
        unitTop: {
            type: Boolean,
            default: false
        },
        //圆角设置
        radius: {
            type: Boolean,
            default: false
        },
        //头部背景色
        headerBackground: {
            type: String,
            default: '#fff'
        },
        //根据实际调整，不建议使用深颜色
        bodyBackground: {
            type: String,
            default: '#fff'
        },
        //单位置顶时，单位条背景色
        unitBackground: {
            type: String,
            default: '#fff'
        }
    },
    data() {
        return {
            isShow: false,
            years: [],
            months: [],
            days: [],
            hours: [],
            minutes: [],
            seconds: [],
            year: 0,
            month: 0,
            day: 0,
            hour: 0,
            minute: 0,
            second: 0,
            startDate: '',
            endDate: '',
            value: [0, 0, 0, 0, 0, 0],
            reset: false
        }
    },
    mounted() {
        this.initData()
    },
    computed: {
        yearOrMonth() {
            return `${this.year}-${this.month}`
        },
        propsChange() {
            return `${this.setDateTime}-${this.type}-${this.startYear}-${this.endYear}`
        }
    },
    watch: {
        yearOrMonth() {
            this.setDays()
        },
        propsChange() {
            this.reset = true
            setTimeout(() => {
                this.initData()
            }, 10)
        }
    },
    methods: {
        stop() {},
        formatNum: function(num) {
            return num < 10 ? '0' + num : num + ''
        },
        generateArray: function(start, end) {
            return Array.from(new Array(end + 1).keys()).slice(start)
        },
        getIndex: function(arr, val) {
            let index = arr.indexOf(val)
            return ~index ? index : 0
        },
        //日期时间处理
        initSelectValue() {
            let fdate = this.setDateTime.replace(/\-/g, '/')
            fdate =
                fdate && fdate.indexOf('/') == -1
                    ? `2020/01/01 ${fdate}`
                    : fdate
            let time = null
            if (fdate) time = new Date(fdate)
            else time = new Date()
            this.year = time.getFullYear()
            this.month = time.getMonth() + 1
            this.day = time.getDate()
            this.hour = time.getHours()
            this.minute = time.getMinutes()
            this.second = time.getSeconds()
        },
        initData() {
            this.initSelectValue()
            this.reset = false
            switch (this.type) {
                case 1:
                    this.value = [0, 0, 0, 0, 0]
                    this.setYears()
                    this.setMonths()
                    this.setDays()
                    this.setHours()
                    this.setMinutes()
                    break
                case 2:
                    this.value = [0, 0, 0]
                    this.setYears()
                    this.setMonths()
                    this.setDays()
                    break
                case 3:
                    this.value = [0, 0]
                    this.setYears()
                    this.setMonths()
                    break
                case 4:
                    this.value = [0, 0]
                    this.setHours()
                    this.setMinutes()
                    break
                case 5:
                    this.value = [0, 0, 0]
                    this.setHours()
                    this.setMinutes()
                    this.setSeconds()
                    break
                case 6:
                    this.value = [0, 0]
                    this.setMinutes()
                    this.setSeconds()
                    break
                case 7:
                    this.value = [0, 0, 0, 0, 0, 0]
                    this.setYears()
                    this.setMonths()
                    this.setDays()
                    this.setHours()
                    this.setMinutes()
                    this.setSeconds()
                    break
                default:
                    break
            }
        },
        setYears() {
            this.years = this.generateArray(this.startYear, this.endYear)
            setTimeout(() => {
                this.$set(this.value, 0, this.getIndex(this.years, this.year))
            }, 8)
        },
        setMonths() {
            this.months = this.generateArray(1, 12)
            setTimeout(() => {
                this.$set(this.value, 1, this.getIndex(this.months, this.month))
            }, 8)
        },
        setDays() {
            if (this.type == 3 || this.type == 4) return
            let totalDays = new Date(this.year, this.month, 0).getDate()
            this.days = this.generateArray(1, totalDays)
            setTimeout(() => {
                this.$set(this.value, 2, this.getIndex(this.days, this.day))
            }, 8)
        },
        setHours() {
            this.hours = this.generateArray(0, 23)
            setTimeout(() => {
                let index =
                    this.type == 5 || this.type == 7
                        ? this.value.length - 3
                        : this.value.length - 2
                this.$set(
                    this.value,
                    index,
                    this.getIndex(this.hours, this.hour)
                )
            }, 8)
        },
        setMinutes() {
            this.minutes = this.generateArray(0, 59)
            setTimeout(() => {
                let index =
                    this.type > 4
                        ? this.value.length - 2
                        : this.value.length - 1
                this.$set(
                    this.value,
                    index,
                    this.getIndex(this.minutes, this.minute)
                )
            }, 8)
        },
        setSeconds() {
            this.seconds = this.generateArray(0, 59)
            setTimeout(() => {
                this.$set(
                    this.value,
                    this.value.length - 1,
                    this.getIndex(this.seconds, this.second)
                )
            }, 8)
        },
        show() {
            setTimeout(() => {
                this.isShow = true
            }, 50)
        },
        hide() {
            this.isShow = false
            this.$emit('cancel', {})
        },
        change(e) {
            this.value = e.detail.value
            switch (this.type) {
                case 1:
                    this.year = this.years[this.value[0]]
                    this.month = this.months[this.value[1]]
                    this.day = this.days[this.value[2]]
                    this.hour = this.hours[this.value[3]]
                    this.minute = this.minutes[this.value[4]]
                    break
                case 2:
                    this.year = this.years[this.value[0]]
                    this.month = this.months[this.value[1]]
                    this.day = this.days[this.value[2]]
                    break
                case 3:
                    this.year = this.years[this.value[0]]
                    this.month = this.months[this.value[1]]
                    break
                case 4:
                    this.hour = this.hours[this.value[0]]
                    this.minute = this.minutes[this.value[1]]
                    break
                case 5:
                    this.hour = this.hours[this.value[0]]
                    this.minute = this.minutes[this.value[1]]
                    this.second = this.seconds[this.value[2]]
                    break
                case 6:
                    this.minute = this.minutes[this.value[0]]
                    this.second = this.seconds[this.value[1]]
                    break
                case 7:
                    this.year = this.years[this.value[0]]
                    this.month = this.months[this.value[1]]
                    this.day = this.days[this.value[2]]
                    this.hour = this.hours[this.value[3]]
                    this.minute = this.minutes[this.value[4]]
                    this.second = this.seconds[this.value[5]]
                    break
                default:
                    break
            }
        },
        btnFix() {
            setTimeout(() => {
                let result = {}
                let year = this.year
                let month = this.formatNum(this.month || 0)
                let day = this.formatNum(this.day || 0)
                let hour = this.formatNum(this.hour || 0)
                let minute = this.formatNum(this.minute || 0)
                let second = this.formatNum(this.second || 0)
                switch (this.type) {
                    case 1:
                        result = {
                            year: year,
                            month: month,
                            day: day,
                            hour: hour,
                            minute: minute,
                            result: `${year}-${month}-${day} ${hour}:${minute}`
                        }
                        break
                    case 2:
                        result = {
                            year: year,
                            month: month,
                            day: day,
                            result: `${year}-${month}-${day}`
                        }
                        break
                    case 3:
                        result = {
                            year: year,
                            month: month,
                            result: `${year}-${month}`
                        }
                        break
                    case 4:
                        result = {
                            hour: hour,
                            minute: minute,
                            result: `${hour}:${minute}`
                        }
                        break
                    case 5:
                        result = {
                            hour: hour,
                            minute: minute,
                            second: second,
                            result: `${hour}:${minute}:${second}`
                        }
                        break
                    case 6:
                        result = {
                            minute: minute,
                            second: second,
                            result: `${minute}:${second}`
                        }
                        break
                    case 7:
                        result = {
                            year: year,
                            month: month,
                            day: day,
                            hour: hour,
                            minute: minute,
                            second: second,
                            result: `${year}-${month}-${day} ${hour}:${minute}:${second}`
                        }
                        break
                    default:
                        break
                }
                this.$emit('confirm', result)
                this.hide()
            }, 80)
        }
    }
}
</script>

<style scoped>
.tui-datetime-picker {
    position: relative;
    z-index: 996;
}

.tui-picker-view {
    height: 100%;
    box-sizing: border-box;
}

.tui-mask {
    position: fixed;
    z-index: 997;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background-color: rgba(0, 0, 0, 0.6);
    visibility: hidden;
    opacity: 0;
    transition: all 0.3s ease-in-out;
}

.tui-mask-show {
    visibility: visible !important;
    opacity: 1 !important;
}

.tui-header {
    z-index: 998;
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    transition: all 0.3s ease-in-out;
    transform: translateY(100%);
}

.tui-date-header {
    width: 100%;
    height: 52rpx;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 26rpx;
    line-height: 26rpx;
    /* #ifdef MP */
    box-shadow: 0 15rpx 10rpx -15rpx #efefef;
    /* #endif */
    /* #ifndef MP */
    box-shadow: 0 15rpx 10rpx -15rpx #888;
    /* #endif */
    position: relative;
    z-index: 2;
}

.tui-date-unit {
    flex: 1;
    text-align: center;
}

.tui-show {
    transform: translateY(0);
}

.tui-picker-header {
    width: 100%;
    height: 90rpx;
    padding: 0 40rpx;
    display: flex;
    justify-content: space-between;
    align-items: center;
    box-sizing: border-box;
    font-size: 32rpx;
    position: relative;
}

.tui-date-radius {
    border-top-left-radius: 20rpx;
    border-top-right-radius: 20rpx;
    overflow: hidden;
}

.tui-picker-header::after {
    content: '';
    position: absolute;
    border-bottom: 1rpx solid #eaeef1;
    -webkit-transform: scaleY(0.5);
    transform: scaleY(0.5);
    bottom: 0;
    right: 0;
    left: 0;
}

.tui-picker-body {
    width: 100%;
    height: 520rpx;
    overflow: hidden;
}

.tui-column-item {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 36rpx;
    color: #333;
}

.tui-font-size_32 {
    font-size: 32rpx !important;
}

.tui-unit-text {
    font-size: 24rpx !important;
    padding-left: 8rpx;
}

.tui-btn-picker {
    padding: 16rpx;
    box-sizing: border-box;
    text-align: center;
    text-decoration: none;
}

.tui-opacity {
    opacity: 0.5;
}
</style>
